package com.zone.editor.photoEditor;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.zone.editor.inter.DrawingView;
import com.zone.editor.shape.*;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.VisibleForTesting;

import com.zone.editor.shape.BrushShape;
import com.zone.editor.shape.AbstractShape;
import com.zone.editor.shape.ShapeAndPaint;
import com.zone.editor.shape.ShapeType;

import java.util.Stack;


public class PhotoDrawingView extends DrawingView {

    protected static final Stack<ShapeAndPaint> drawShapes = new Stack<>();
    protected static final Stack<ShapeAndPaint> redoShapes = new Stack<>();

    public PhotoDrawingView(Context context) {
        this(context, null);
    }

    public PhotoDrawingView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PhotoDrawingView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        for (ShapeAndPaint shape : drawShapes) {
            shape.getShape().draw(canvas, shape.getPaint());
        }
    }

    @Override
    public void createShape() {
        final AbstractShape shape;
        Paint paint = createPaint(isErasing);
        if (isErasing) {
            shape = new BrushShape();
            paint = createEraserPaint();
        } else if (currentShapeBuilder.getShapeType() == ShapeType.OVAL) {
            shape = new OvalShape();
        } else if (currentShapeBuilder.getShapeType() == ShapeType.RECTANGLE) {
            shape = new RectangleShape();
        } else if (currentShapeBuilder.getShapeType() == ShapeType.LINE) {
            shape = new LineShape();
        } else {
            shape = new BrushShape();
        }
        currentShape = new ShapeAndPaint(shape, paint);
        drawShapes.push(currentShape);

        if (viewChangeListener != null) {
            viewChangeListener.onStartDrawing();
        }
    }

    @Override
    protected void endShape(float touchX, float touchY) {
        if (currentShape.getShape().hasBeenTapped()) {
            // just a tap, this is not a shape, so remove it
            drawShapes.remove(currentShape);
            //handleTap(touchX, touchY);
        }

        if (viewChangeListener != null) {
            viewChangeListener.onStopDrawing();
            viewChangeListener.onViewAdd(this);
        }
    }
    @Override
    public boolean redo() {
        if (!redoShapes.empty()) {
            drawShapes.push(redoShapes.pop());
            invalidate();
        }

        if (viewChangeListener != null) {
            viewChangeListener.onViewAdd(this);
        }
        return !redoShapes.empty();
    }
    @Override
    // region eraser
    public void brushEraser() {
        isEnabled = true;
        isErasing = true;
    }
    @Override
    public void setBrushEraserSize(float brushEraserSize) {
        mBrushEraserSize = brushEraserSize;
    }
    @Override
    public float getEraserSize() {
        return mBrushEraserSize;
    }
    // endregion
    @Override
    // region Setters/Getters
    public void setShapeBuilder(ShapeBuilder shapeBuilder) {
        currentShapeBuilder = shapeBuilder;
    }
    @Override
    public void enableDrawing(boolean brushDrawMode) {
        isEnabled = brushDrawMode;
        isErasing = !brushDrawMode;
        if (brushDrawMode) {
            setVisibility(View.VISIBLE);
        }
    }
    @Override
    public boolean isDrawingEnabled() {
        return isEnabled;
    }
    @Override
    @VisibleForTesting
    public ShapeAndPaint getCurrentShape() {
        return currentShape;
    }
    @Override
    @VisibleForTesting
    public ShapeBuilder getCurrentShapeBuilder() {
        return currentShapeBuilder;
    }
//    @Override
////    @VisibleForTesting
//    public Pair<Stack<ShapeAndPaint>, Stack<ShapeAndPaint>> getDrawingPath() {
//        return new Pair<>(drawShapes, redoShapes);
//    }
    @Override
    public void clearAll() {
        drawShapes.clear();
        redoShapes.clear();
        invalidate();
    }
    @Override
    public boolean undo() {
        if (!drawShapes.empty()) {
            redoShapes.push(drawShapes.pop());
            invalidate();
        }
        if (viewChangeListener != null) {
            viewChangeListener.onViewRemoved(this);
        }
        return !drawShapes.empty();
    }

}

